package controller;

import entities.BasePiece;
import listener.MessageListener;
import listener.PiecesListener;
import org.json.JSONObject;
import util.MyClient;
import view.ChatPanel;
import view.ChessBoard;
import view.FindPlayerPanel;
import view.MainFrame;

import javax.swing.*;
import java.awt.*;
import java.text.SimpleDateFormat;
import java.util.Date;

/***
 * Author: Mr.Zhao, Time: 2018/5/24/10:17
 * Description: 在线游戏控制器，处理来自服务端的消息，根据消息移动棋子
 *              （由原GameController重构）
 */
public class OnlineGameGameController extends GameController implements PiecesListener, MessageListener {
    private MainFrame mainFrame;
    private Color myColor;
    private MyClient client;
    private ChessBoard chessBoard;
    private FindPlayerPanel findPlayerPanel = null;
    private ChatPanel chatPanel = null;
    private ChatPanelController chatPanelController = null;

    public OnlineGameGameController(MainFrame mainFrame) {
        super(mainFrame.getChessBoard());
        this.mainFrame = mainFrame;
        this.chessBoard = mainFrame.getChessBoard();
        this.findPlayerPanel = mainFrame.getFindPlayerPanel();
        client = MyClient.getInstance();
    }

    /**
     * 接收到了玩家的游戏邀请，
     * 显示提示对话框，是否接受邀请。
     * 根据选择不同向服务器发送不同的信息
     *
     * @param id 玩家的id
     */
    @Override
    public void receiveInvitation(String id) {
        String str = String.format("收到了玩家%s的游戏邀请，是否接受？", id);
        int n = JOptionPane.showConfirmDialog(mainFrame, str, "收到玩家邀请", JOptionPane.YES_NO_OPTION);
        JSONObject json = new JSONObject();
        json.put("to", id);
        if (n == JOptionPane.YES_OPTION) {
            json.put("flag", "接受游戏邀请");
        } else {
            json.put("flag", "拒绝游戏邀请");
        }
        client.sendMessage(json.toString());
    }

    /**
     * 我方发送的请求被玩家接受了，
     * 根据服务器返回的我方棋子颜色开始新游戏
     *
     * @param color 我方棋子颜色
     */
    @Override
    public void gameStart(Color color) {
        myColor = color;
        super.startGame(myColor);
        replaceFindPlayerPanelByChatPanel();
        for (BasePiece piece : super.pieces) {
            piece.addPiecesListener(this);
        }
    }


    /**
     * 我方发送的请求被玩家拒绝了
     */
    @Override
    public void refusedInvitation() {
        JOptionPane.showConfirmDialog(mainFrame, "对方可能觉得您有些丑，拒绝了您的邀请！",
                "邀请被拒绝", JOptionPane.DEFAULT_OPTION);
    }


    /**
     * 收到对手走棋信息
     *
     * @param x1 走棋前x坐标
     * @param y1 走棋前y坐标
     * @param x2 走棋后x坐标
     * @param y2 走棋后y坐标
     */
    @Override
    public void opponentMoved(int x1, int y1, int x2, int y2) {

        Point p1 = transformPoint(x1, y1);
        Point p2 = transformPoint(x2, y2);
        BasePiece piece1 = super.pointPieceMap.get(p1);
        BasePiece piece2 = super.pointPieceMap.get(p2);
        /* 移动的位置有我方棋子则可以吃掉我方棋子 */
        if (piece2 != null && piece2.getColor() == myColor) {
            super.eatPiece(piece1, piece2);
        } else {
            piece1.moveTo(p2.x, p2.y);
        }
    }

    @Override
    public void opponentOffline() {
        JOptionPane.showConfirmDialog(mainFrame, "对手已掉线",
                "提示", JOptionPane.DEFAULT_OPTION);
        this.endGame();
    }

    /**
     * 我方棋子移动监听
     *
     * @param piece
     */
    public void afterPieceMoved(BasePiece piece) {
        super.afterPieceMoved(piece);
        if (piece.getColor() == myColor) {
            int x1 = piece.getLastPosition().x;
            int y1 = piece.getLastPosition().y;
            int x2 = piece.getPosition().x;
            int y2 = piece.getPosition().y;
            JSONObject json = new JSONObject();
            json.put("flag", "走棋");
            json.put("x1", x1);
            json.put("y1", y1);
            json.put("x2", x2);
            json.put("y2", y2);
            client.sendMessage(json.toString());
        }
    }

    public void beforePieceMoved(BasePiece piece) {
        super.beforePieceMoved(piece);
    }

    /**
     * 游戏开局后，把寻找玩家面板替换为聊天面板
     * 同时添加相应的监听器
     */
    private void replaceFindPlayerPanelByChatPanel() {
        if (chatPanel == null) {
            chatPanel = new ChatPanel();
        }
        if (chatPanelController == null) {
            chatPanelController = new ChatPanelController(chatPanel);
            client.addMessageListener(chatPanelController);
        }
        mainFrame.remove(findPlayerPanel);
        chatPanel.setLocation(chessBoard.getWidth(), chessBoard.getMargin());
        mainFrame.add(chatPanel);
        mainFrame.validate();
        mainFrame.repaint();
    }

    /**
     * 游戏结束，把聊天面板替换为寻找玩家面板
     */
    private void replaceChatPanelByFindPlayerPanel() {
        if (chatPanel == null) {
            return;
        }
        mainFrame.remove(chatPanel);
        findPlayerPanel.setLocation(chessBoard.getWidth(), chessBoard.getMargin());
        findPlayerPanel.getjList().removeAll();
        mainFrame.add(findPlayerPanel);
        mainFrame.validate();
        mainFrame.repaint();
    }

    @Override
    protected boolean isCheckmate(BasePiece piece) {
        if (super.isCheckmate(piece)) {
            JSONObject json = new JSONObject();
            json.put("flag", "聊天");
            SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
            String time = sdf.format(new Date());
            json.put("time", time);
            json.put("content", "我已将军，请小心应对！(自动发送)");
            client.sendMessage(json.toString());
            return true;
        }
        return false;
    }

    @Override
    protected void endGame() {
        super.endGame();
        replaceChatPanelByFindPlayerPanel();
    }


    /**
     * 将对手的坐标转化为我方棋盘的坐标
     *
     * @param x
     * @param y
     * @return 我方棋盘坐标
     */
    private Point transformPoint(int x, int y) {
        return new Point(ChessBoard.WIDTH - x, ChessBoard.HEIGHT - y);
    }

    @Override
    public void listPlayers(String msg) {
    }

    @Override
    public void receivedChatMsg(String time, String content) {

    }

    @Override
    public void myInfo(String myInfo) {

    }
}
